package start.signature;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.Base64;
import java.util.Date;

public class AccountEncryptionWithExpiryExample {

    private static final long EXPIRY_DURATION = 5 * 60 * 1000; // 5 minutes in milliseconds

    public static void main(String[] args) {
        try {
            // Simulate the transmission of account and key
            String account = "00002251";
            String secretKey = "6163B3F782F9637AE1EE901B5ACC6EBB"; // This key should be securely shared between parties

            // Generate a secret key for encryption
            SecretKey encryptionKey = generateSecretKey(secretKey);

            // Simulate the generation of encrypted data
            String encryptedData = encryptAccountAndTimestamp(account, encryptionKey);

            //nQNK4W5JvNE5A0NLh+ODSsg6qOQBcuJ5EjtztN3xyNk=
            //encryptedData = "nQNK4W5JvNE5A0NLh+ODSsg6qOQBcuJ5EjtztN3xyNk=";

            // Simulate the decryption of account data
            String decryptedAccount = decryptAccountAndTimestamp(encryptedData, encryptionKey);

            // Verify the expiration time after decryption
            //boolean isExpired = isDataExpired(encryptedData);
            //System.out.println("Is Data Expired: " + isExpired);

            System.out.println("原始数据: " + account);
            System.out.println("加密后数据: " + encryptedData);
            System.out.println("解密后数据: " + decryptedAccount);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static SecretKey generateSecretKey(String key) throws Exception {
        KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
        keyGenerator.init(128); // You can use 128, 192, or 256 bits
        return new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "AES");
    }

    private static String encryptAccountAndTimestamp(String account, SecretKey key) throws Exception {
        // Combine account and current timestamp
        String dataToEncrypt = account + "^" + getCurrentTimestamp();

        // Encrypt the combined data using the shared secret key
        String encryptedData = encrypt(dataToEncrypt, key);
        return encryptedData;
    }

    private static String decryptAccountAndTimestamp(String encryptedData, SecretKey key) throws Exception {
        // Decrypt the encrypted data using the shared secret key
        String decryptedData = decrypt(encryptedData, key);

        // Split the decrypted data using the "^" delimiter
        String[] parts = decryptedData.split("\\^");
        if (parts.length >= 2) {
            // Extract account and timestamp
            String account = parts[0];
            long timestamp = Long.parseLong(parts[1]);

            // Validate expiry timestamp
            long expiryTimestamp = timestamp + EXPIRY_DURATION;
            if (System.currentTimeMillis() <= expiryTimestamp) {
                return account; // Extract and return the account data
            } else {
                throw new RuntimeException("数据已过期");
            }
        } else {
            throw new IllegalArgumentException("数据格式无效");
        }
    }



    private static String encrypt(String data, SecretKey key) throws Exception {
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.ENCRYPT_MODE, key);
        byte[] encryptedBytes = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
        return Base64.getEncoder().encodeToString(encryptedBytes);
    }

    private static String decrypt(String encryptedData, SecretKey key) throws Exception {
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.DECRYPT_MODE, key);
        byte[] encryptedBytes = Base64.getDecoder().decode(encryptedData);
        byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
        return new String(decryptedBytes, StandardCharsets.UTF_8);
    }

    private static String getCurrentTimestamp() {
        return String.valueOf(System.currentTimeMillis());
    }
}
